home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / mac / files / t_sys5 / unixcpio.gz / unixnet.cpio / fingcli.c < prev    next >
C/C++ Source or Header  |  1994-07-11  |  6KB  |  286 lines

  1. /*
  2.  *
  3.  *    Finger support...
  4.  *
  5.  *    Finger client routines.  Written by Michael T. Horne - KA7AXD.
  6.  *    Copyright 1988 by Michael T. Horne, All Rights Reserved.
  7.  *    Permission granted for non-commercial use and copying, provided
  8.  *    that this notice is retained.
  9.  *
  10.  */
  11.  
  12. #include <stdio.h>
  13. #include "config.h"
  14. #include "global.h"
  15. #include "mbuf.h"
  16. #include "timer.h"
  17. #include "internet.h"
  18. #include "icmp.h"
  19. #include "netuser.h"
  20. #include "tcp.h"
  21. #include "ftp.h"
  22. #include "telnet.h"
  23. #include "iface.h"
  24. #include "ax25.h"
  25. #include "lapb.h"
  26. #include "finger.h"
  27. #include "session.h"
  28. #include "nr4.h"
  29. #ifdef    UNIX
  30. #include <string.h>
  31. #endif
  32.  
  33. extern char    badhost[],
  34.         hostname[];
  35.  
  36. /*
  37.  *
  38.  *    Open up a socket to a remote (or the local) host on its finger port.
  39.  *
  40.  */
  41.  
  42. int
  43. dofinger(argc,argv)
  44. int    argc;
  45. char    *argv[];
  46. {
  47.     void        f_state(),
  48.             fingcli_rcv();
  49.     char        *inet_ntoa();
  50.     int32        resolve();
  51.     struct session    *s;
  52.     struct tcb    *tcb;
  53.     struct socket    lsocket,
  54.             fsocket;
  55.     struct finger    *finger,
  56.                     *alloc_finger();
  57.     char        *host;
  58.  
  59.     if (argc < 2) {
  60.         printf("usage: %s [user | user@host | @host]\n", argv[0]);
  61.         return(1);
  62.     }
  63.  
  64.     lsocket.address = ip_addr;
  65.     lsocket.port = lport++;
  66.  
  67. /*
  68.  *    Extract user/host information.  It can be of the form:
  69.  *    
  70.  *    finger user,            # finger local user
  71.  *    finger user@host,        # finger remote user
  72.  *    finger @host            # finger host (give system status)
  73.  *
  74.  */
  75.     if ((finger = alloc_finger()) == NULLFING)
  76.         return(1);
  77.  
  78.     if ((host = index(argv[1], '@')) == NULL) {
  79.         fsocket.address = ip_addr;    /* no host, use local */
  80.         if ((finger->user = malloc((unsigned)(strlen(argv[1]) + 3))) == NULL) {
  81.             free_finger(finger);
  82.             return(1);
  83.         }
  84.         strcpy(finger->user, argv[1]);
  85.         strcat(finger->user, "\015\012");
  86.     }
  87.     else {
  88.         *host++ = '\0';        /* null terminate user name */
  89.         if (*host == '\0') {    /* must specify host */
  90.             printf("%s: no host specified\n", argv[0]);
  91.             printf("usage: %s [user | user@host | @host]\n",
  92.                 argv[0]);
  93.             free_finger(finger);
  94.             return(1);
  95.         }
  96.         if ((fsocket.address = resolve(host)) == 0) {
  97.             printf("%s: ", argv[0]);
  98.             printf(badhost, host); 
  99.             free_finger(finger);
  100.             return(1);
  101.         }
  102.         if ((finger->user = malloc((unsigned)(strlen(argv[1])+3)))==NULL) {
  103.             free_finger(finger);
  104.             return 1;
  105.         }
  106.         strcpy(finger->user, argv[1]);
  107.         strcat(finger->user, "\015\012");
  108.     }
  109.     
  110.     fsocket.port = FINGER_PORT;        /* use finger wnp */
  111.  
  112.     /* Allocate a session descriptor */
  113.     if ((s = newsession()) == NULLSESSION){
  114.         printf("Too many sessions\n");
  115.         free_finger(finger);
  116.         return 1;
  117.     }
  118.     current = s;
  119.     s->cb.finger = finger;
  120.     finger->session = s;
  121.  
  122.     if (!host)                /* if no host specified */
  123.         host = hostname;        /* use local host name */
  124.     if ((s->name = malloc((unsigned)(strlen(host)+1))) != NULLCHAR)
  125.         strcpy(s->name, host);
  126.  
  127.     s->type = FINGER;
  128.     s->parse = (int (*)()) NULL;
  129.  
  130.     tcb = open_tcp(&lsocket, &fsocket, TCP_ACTIVE, 0,
  131.      fingcli_rcv, (void (*)()) 0, f_state, 0, (char *) finger);
  132.  
  133.     finger->tcb = tcb;
  134.     tcb->user = (char *)finger;
  135.     go();
  136.     return 0;
  137. }
  138.  
  139. /*
  140.  *    Allocate a finger structure for the new session
  141.  */
  142. struct finger *
  143. alloc_finger()
  144. {
  145.     struct finger *tmp;
  146.  
  147.     if ((tmp = (struct finger *) malloc(sizeof(struct finger))) == NULLFING)
  148.         return(NULLFING);
  149.     tmp->session = NULLSESSION;
  150.     tmp->user = (char *) NULL;
  151.     return(tmp);
  152. }
  153.  
  154. /*
  155.  *    Free a finger structure
  156.  */
  157. int
  158. free_finger(finger)
  159. struct finger *finger;
  160. {
  161.     if (finger != NULLFING) {
  162.         if (finger->session != NULLSESSION)
  163.             freesession(finger->session);
  164.         if (finger->user != (char *) NULL)
  165.             free(finger->user);
  166.         free((char *)finger);
  167.     }
  168.     return 0;
  169. }
  170.  
  171. /* Finger receiver upcall routine */
  172. void
  173. fingcli_rcv(tcb, cnt)
  174. register struct tcb    *tcb;
  175. int16            cnt;
  176. {
  177.     struct mbuf    *bp;
  178.     char        *buf;
  179.  
  180.     /* Make sure it's a valid finger session */
  181.     if ((struct finger *) tcb->user == NULLFING) {
  182.         return;
  183.     }
  184.  
  185.     /* Hold output if we're not the current session */
  186.     if (mode != CONV_MODE || current == NULLSESSION
  187.         || current->type != FINGER)
  188.         return;
  189.  
  190.     /*
  191.      *    We process the incoming data stream and make sure it
  192.      *    meets our requirments.  A check is made for control-Zs
  193.      *    since these characters lock up DoubleDos when sent to
  194.      *    the console (don't you just love it...).
  195.      */
  196.  
  197.     if (recv_tcp(tcb, &bp, cnt) > 0)
  198.         while (bp != NULLBUF) {
  199.             buf = bp->data;
  200.             while(bp->cnt--) {
  201.                 switch(*buf) {
  202.                     case '\012':    /* ignore LF */
  203.                     case '\032':    /* NO ^Z's! */
  204.                         break;
  205.                     case '\015':
  206.                         fputc('\015', stdout);
  207.                         fputc('\012', stdout);
  208.                         break;
  209.                     default:
  210.                         fputc(*buf, stdout);
  211.                         break;
  212.                 }
  213.                 buf++;
  214.             }
  215.             bp = free_mbuf(bp);
  216.         }
  217.     fflush(stdout);
  218. }
  219.  
  220. /* State change upcall routine */
  221. /*ARGSUSED*/
  222. void
  223. f_state(tcb,old,new)
  224. register struct tcb    *tcb;
  225. char            old,        /* old state */
  226.             new;        /* new state */
  227. {
  228.     struct finger    *finger;
  229.     char        notify = 0;
  230.     extern char    *tcpstates[];
  231.     extern char    *reasons[];
  232.     extern char    *unreach[];
  233.     extern char    *exceed[];
  234.     struct mbuf    *bp;
  235.  
  236.     finger = (struct finger *)tcb->user;
  237.  
  238.     if(current != NULLSESSION && current->type == FINGER)
  239.         notify = 1;
  240.  
  241.     switch(new){
  242.  
  243.     case CLOSE_WAIT:
  244.         if(notify)
  245.             printf("%s\n",tcpstates[new]);
  246.         close_tcp(tcb);
  247.         break;
  248.  
  249.     case CLOSED:    /* finish up */
  250.         if(notify) {
  251.             printf("%s (%s", tcpstates[new], reasons[tcb->reason]);
  252.             if (tcb->reason == NETWORK){
  253.                 switch(tcb->type){
  254.                 case DEST_UNREACH:
  255.                     printf(": %s unreachable",unreach[tcb->code]);
  256.                     break;
  257.                 case TIME_EXCEED:
  258.                     printf(": %s time exceeded",exceed[tcb->code]);
  259.                     break;
  260.                 }
  261.             }
  262.             printf(")\n");
  263.             cmdmode();
  264.         }
  265.         if(finger != NULLFING)
  266.             free_finger(finger);
  267.         del_tcp(tcb);
  268.         break;
  269.     case ESTABLISHED:
  270.         if (notify) {
  271.             printf("%s\n",tcpstates[new]);
  272.         }
  273.         printf("[%s]\n", current->name);
  274.         bp = qdata(finger->user, (int16) strlen(finger->user));
  275.         send_tcp(tcb, bp);
  276.         break;
  277.         
  278.     default:
  279.         if(notify)
  280.             printf("%s\n",tcpstates[new]);
  281.         break;
  282.     }
  283.     fflush(stdout);
  284. }
  285.  
  286.